<?php
namespace app\common\model;

use think\model\concern\SoftDelete;

class User extends Base
{
    use SoftDelete;
    protected $deleteTime = 'delete_time';

    public function getAvatarsAttr($val)
    {
        if(stripos($val, 'thirdwx.qlogo.cn') !== false) return $val;
        return getUrl() . $val;
    }

    public function getLastAttr($val)
    {
        if(!$val) return '';
        return date('Y-m-d H:i:s', $val);
    }

    public function getJobTimeAttr($val)
    {
        if(!$val) return '';
        return date('Y-m-d', $val);
    }

    /**
     * 用户是否授权
     */
    public static function isAuth($userId = 0)
    {
        $info = self::getFind(['id' => $userId]);
        if($info === false) return false;
        if($info['name'] == '') return false;
        return true;
    }

    /**
     * 生成工资表
     */
    public static function setSalary()
    {
        $time = strtotime('-1 months');
        $day  = date('Y-m', $time);
        list($year, $month) = explode('-', date('Y-m', $time));
        $quitTime = strtotime($year . '-' . $month);

        $where[] = ['u.is_staff', '=', 1];
        $where[] = ['u.company_id', '=', 1];
        // $where[] = ['u.id', '=', 230];

        $userList = self::alias('u')
            ->join('user_section us', 'u.section_id=us.id')
            ->join('rule_salary rs', 'u.rule_salary_id=rs.id')
            ->where($where)
            ->where('(u.status=1 and u.quit_time=0) or (u.status=2 and u.quit_time>' . $quitTime . ')')
            ->field([
                'u.id', 
                'u.section_id', 
                'u.name', 
                'u.card_num', 
                'u.is_trial', 
                'u.is_trial_salary', 
                'u.rule_salary_id', 
                'u.probation', 
                'u.job_time', 
                'u.subsidy',
                'u.social',
                'us.name as section_name',
                'us.traffic',
                'us.telephone',
                'us.attendance',
                'us.meal',
                'rs.achiev',
                'rs.salary',
            ])
            ->select();

        /** 计入考勤的休息天数 */
        $quitToCheck = Calendar::getNum(['g_year' => $year, 'g_month' => $month, 'status' => 3, 'is_check' => 1]);

        /** 应出勤天数 */
        $checkDay = Calendar::getCheckDay($time);

        /** 生成或更新 */
        $isSet = 0;

        /** 查询本月数据 */
        $userWagesId = UserWages::whereMonth('date_time', $day)->value('id');
        if($userWagesId) $isSet = 1;

        $salaryData = [];
        foreach($userList as &$info){
            /** 是否享受全勤 */
            $isAttendance = 1;

            /** 实际出勤天数 */
            $checkDayEealith = CheckClock::getClockDays($info['id'], $day);
            if($checkDayEealith == 0) continue;
            if($checkDayEealith > $checkDay) $checkDayEealith = $checkDay;

            /** 请假时长 */
            $leaveNum = CheckClock::getLeaveDuration($info['id'], $day);
            if($leaveNum >= 0.5) $isAttendance = 0.5;
            if($leaveNum >= 1) $isAttendance = 0;

            /** 旷工天数 */
            $workNeglectNum = CheckClock::getWorkNeglectNums($info['id'], $day);
            if($workNeglectNum > 0) $isAttendance = 0;

            /** 加班时长 */
            $workOverNum = CheckClock::getWorkOverNum($info['id'], $day);

            /** 迟到次数 */
            $lateNum = CheckClock::getLateNums($info['id'], $day, 2);

            /** 缺卡次数 */
            $missCardNum = CheckClock::getMissCardNums($info['id'], $day);

            /** 缺卡五次以上扣除一天工资和全部全勤 */
            if($missCardNum > 5){
                $checkDayEealith -= $checkDayEealith;
                $isAttendance = 0;
            }

            /** 日工资 */
            if($info['is_trial'] == 1 && $info['is_trial_salary'] == 0){
                $salaryEveryday = $checkDayEealith ? $info['salary'] * 0.8 / ($checkDay + $quitToCheck) : 0;
            }else{
                $salaryEveryday = $checkDayEealith ? $info['salary'] / ($checkDay + $quitToCheck) : 0;
            }

            /** 提成和绩效系数 */
            if(strpos($info['section_name'], '交付') !== false){
                $commissionArr = self::setCommission($info['id'], $day);

                $commission  = $commissionArr['commission'];
                $achievRadio = $commissionArr['achiev_radio'];
            }else if(strpos($info['section_name'], '商务') !== false){
                $commission = $achievRadio = 0;
            }else{
                $commission = $achievRadio = 0;
            }

            /** 交通补助 */
            $traffic = $checkDayEealith ? rounding($info['traffic'] * ($checkDayEealith / $checkDay)) : 0;

            /** 话补 */
            $telephone = $checkDayEealith ? rounding($info['telephone'] * ($checkDayEealith / $checkDay)) : 0;

            /** 实际出勤天数 */
            $realCheckDay = $checkDay + $quitToCheck - $workNeglectNum - $leaveNum;

            $salaryInfo = [
                'user_id'           => $info['id'],
                'name'              => $info['name'],  /** 姓名 */
                'section'           => $info['section_name'],  /** 部门 */
                'card_num'          => $info['card_num'],  /** 银行卡号 */
                'salary'            => $salaryEveryday * $realCheckDay,  /** 基本工资 */
                'salary_days'       => $salaryEveryday,  /** 每日工资 */
                'check_num_must'    => $checkDay + $quitToCheck,  /** 应出勤天数 */
                'check_num_reality' => $realCheckDay, /** 实际出勤天数 */
                'leave_num'         => $leaveNum,  /** 请假时长 */
                'late_num'          => $lateNum,  /** 迟到次数 */
                'miss_card_num'     => $missCardNum,  /** 缺卡次数 */
                'work_over_num'     => $workOverNum,  /** 加班时长 */
                'salary_work'       => 0,  /** 加班费 */
                'achiev'            => $achievRadio ? $achievRadio * $info['achiev'] : 0,  /** 绩效 */
                'commission'        => $commission ? $commission : 0,  /** 提成 */
                'attendance'        => $isAttendance * $info['attendance'],  /** 全勤 */
                'social'            => $info['social'],  /** 社保 */
                'meal'              => $checkDayEealith ? floor($realCheckDay) * $info['meal'] : 0, /** 餐补 */
                'traffic'           => $traffic,  /** 交通补助 */
                'telephone'         => $telephone,  /** 话补 */
                'subsidy'           => $info['subsidy'],  /** 增补 */
                'salary_total'      => 0,  /** 工资总计 */
                'date_time'         => strtotime($day),
                'create_time'       => time(),
            ];

            if($isSet) $salaryInfo['id'] = $userWagesId;
            $salaryData[] = $salaryInfo;
        }

        if($isSet){
            $userWages = new UserWages();
            $userWages->saveAll($salaryData);
        }else{
            UserWages::addAll($salaryData);
        }

        return true;
    }

    /**
     * 计算提成
     * @param int $userId 员工ID
     * @param string $day 日期（年月）
     */
    public static function setCommission($userId, $day)
    {
        $info = KpiRecord::getFind(['user_id' => $userId, 'data_time' => strtotime($day)]);
        if(!$info) return ['commission' => 0, 'achiev_radio' => 0];

        return [
            'commission'   => rounding($info['total'] * $info['achiev_radio']), 
            'achiev_radio' => $info['achiev_radio'],
        ];
    }

    /**
     * 计算交付中心实际绩效
     * @param int $userId 员工ID
     * @param string $time 日期（年月）
     * @param int $achiev 基础绩效
     */
    public static function setAchiev($userId = 0, $time = '', $achiev = 0)
    {
        $kpiRecordInfo = KpiRecord::getFind(['user_id' => $userId, 'data_time' => strtotime($time)]);
        if(!$kpiRecordInfo) return 0;
        if($kpiRecordInfo['score'] < 70) return 0;

        return round($kpiRecordInfo['score'] / 100 * $achiev);
    }




    /**
     * 计算商务提成
     * @param int $userId 员工ID
     * @param string $day 日期（年月）
     */
    public static function setCommissionBusin($userId, $day)
    {
        /** 入职职位ID */
        $joinJobId = ResumeRound::alias('uu')
            ->join('user_resume ur', 'uu.resume_id=ur.id')
            ->where(['ur.share_user_id' => $userId, 'uu.status' => 5])
            ->whereMonth('uu.join_time', $day)
            ->column('uu.job_id');

        /** 总业绩 */
        $total = 0;
        foreach($joinJobId as $jobId){
            $total += Job::getVal(['id' => $jobId], 'total');
        }

        /** 实际入职数量 */
        $joinNumNew = count($joinJobId);

        /** 商务提成规则 */
        $list = RuleKpiBusin::getList([], 0, 0, 0, '*', 'join_high');

        $radio = 0;
        foreach($list as $k => &$info){
            if($k == 0 && $joinNumNew >= $info['join_high']){
                $radio = $info['radio'];
                break;
            }

            if($joinNumNew <= $info['join_high'] && $joinNumNew > $info['join_low']){
                $radio = $info['radio'];
                break;
            }
        }

        return rounding($total * $radio);
    }

    /**
     * 计算商务入职率
     * @param int $userId 员工ID
     * @param string $time 日期（年月）
     */
    public static function setJoinRadio($userId = 0, $time = '')
    {
        /** 发布的职位列表 */
        $jobList = Job::where(['user_id' => $userId])->whereMonth('create_time', $time)->select();
        if($jobList->isEmpty()) return 0;

        $system = getSystem();

        /** 总数量 */
        $jobNum = count($jobList);

        /** 有效职位数量 */
        $joinNum = 0;

        foreach($jobList as $jobInfo){
            /** 入职数量 */
            $joinNum = ResumeRound::alias('uu')
                ->join('user_resume ur', 'uu.resume_id=ur.id')
                ->where(['ur.share_user_id' => $userId, 'uu.job_id' => $jobInfo['id'], 'uu.status' => 5])
                ->whereMonth('uu.join_time', $time)
                ->count();

            if($jobNum / $jobInfo['need_num'] >= $system['join_radio']) $joinNum++;
        }

        return rounding($joinNum / $jobNum);
    }

    /**
     * 获取员工身份
     */
    public static function getUserRole($userId = 0)
    {
        if($userId == 1) return 0;

        $info = self::getFind(['id' => $userId]);
        if(!$info) return 2;
        
        $levelInfo = UserSectionLevel::getFind(['id' => $info['section_level_id']]);

        if($levelInfo && $levelInfo['level'] == 1){
            return 1;
        }

        return 2;
    }





    /** 
     * 出勤天数
     * @param int $userId  员工ID
     * @param string $time 时间（年-月）
     */
    public static function checkDaysNum($userId, $time)
    {
        return CheckClock::whereMonth('create_time', $time)
            ->where([['user_id', '=', $userId], ['clock_type', 'between', [1,2]]])
            ->field("from_unixtime(create_time,'%Y-%m-%d') as time")
            ->group('time')
            ->count();
    }
}